package com.fanvil.videoconference;

import android.os.Parcel;
import android.os.Parcelable;
import android.view.Surface;

public class FvlSurfaceHolder implements Parcelable {

    public static final int ID_INVALID = -1;

    public enum Role {
        INVALID(-1),
        LOCAL(0),
        REMOTE(1),
        REMOTE2(2);

        private int value;

        Role(int value) {
            this.value = value;
        }

        public int value() {
            return this.value;
        }

        public static Role valueOf(int value) {
            for (Role role : Role.values()) {
                if (role.value == value) {
                    return role;
                }
            }
            return INVALID;
        }
    }

    public enum State {
        INVALID(-1),
        CREATED(0),
        CHANGED(1),
        DESTORYED(2);

        private int value;

        State(int value) {
            this.value = value;
        }

        public int value() {
            return this.value;
        }

        public static State valueOf(int value) {
            for (State state : State.values()) {
                if (state.value == value) {
                    return state;
                }
            }
            return INVALID;
        }
    }

    private Surface mSurface = null;
    private Object mRenderer = null;
    private int mId = ID_INVALID;
    private int mRole = Role.INVALID.value();
    private int mState = State.INVALID.value();

    public FvlSurfaceHolder() {
        mSurface = null;
        mRenderer = null;
        mId = ID_INVALID;
        mRole = Role.INVALID.value();
        mState = State.INVALID.value();
    }

    public FvlSurfaceHolder(Surface surface) {
        mSurface = surface;
        mRenderer = null;
        if (isValid()) {
            mId = mSurface.hashCode();
        } else {
            mId = ID_INVALID;
        }
        mRole = Role.INVALID.value();
        mState = State.INVALID.value();
    }

    protected FvlSurfaceHolder(Parcel in) {
        int valid = in.readInt();
        if (valid == 1) {
            mSurface = in.readParcelable(getClass().getClassLoader());
        } else {
            mSurface = null;
        }
        mRenderer = null;
        mId = in.readInt();
        mRole = in.readInt();
        mState = in.readInt();
    }

    public Role getRole() {
        return Role.valueOf(mRole);
    }

    public void setRole(Role role) {
        mRole = role.value();
    }

    public State getState() {
        return State.valueOf(mState);
    }

    public void setState(State state) {
        mState = state.value();
    }

    public Surface getSurface() {
        return mSurface;
    }

    public void setSurface(Surface surface) {
        mSurface = surface;
        if (isValid()) {
            mId = mSurface.hashCode();
        } else {
            mId = ID_INVALID;
        }
    }

    public Object getRenderer() {
        return mRenderer;
    }

    public void setRenderer(Object renderer) {
        mRenderer = renderer;
    }

    public boolean isActive() {
        return isValid() && (mState == State.CREATED.value() || mState == State.CHANGED.value());
    }

    public boolean isValid() {
        return mSurface != null && mSurface.isValid();
    }

    public boolean isLocal() {
        return mRole == Role.LOCAL.value();
    }

    public boolean isRemote() {
        return mRole == Role.REMOTE.value();
    }

    @Override
    public int describeContents() {
        return 0;
    }

    @Override
    public void writeToParcel(Parcel dest, int flags) {
        int valid = isValid() ? 1 : 0;
        dest.writeInt(valid);
        if (isValid()) {
            dest.writeParcelable(mSurface, flags);
            dest.writeInt(mId);
        } else {
            dest.writeInt(ID_INVALID);
        }
        dest.writeInt(mRole);
        dest.writeInt(mState);
    }

    @Override
    public boolean equals(Object obj) {
        if (this == obj)
            return true;

        if (getClass() != obj.getClass()) {
            return false;
        }

        FvlSurfaceHolder b = (FvlSurfaceHolder) obj;
        if (mId == -1 || b.mId == -1) {
            return false;
        }
        return mId == b.mId && mRole == b.mRole;
    }

    @Override
    public String toString() {
        return "FvlSurfaceHolder{" + mSurface
                + ", Id=" + mId
                + ", Role=" + Role.valueOf(mRole).toString()
                + ", State=" + State.valueOf(mState).toString()
                + ", Active=" + isActive()
                + ", Valid=" + isValid()
                + "}";
    }

    public static final Creator<FvlSurfaceHolder> CREATOR = new Creator<FvlSurfaceHolder>() {
        @Override
        public FvlSurfaceHolder createFromParcel(Parcel in) {
            return new FvlSurfaceHolder(in);
        }

        @Override
        public FvlSurfaceHolder[] newArray(int size) {
            return new FvlSurfaceHolder[size];
        }
    };
}

